#include "VStdAfx.h"
#include "VRender.h"
#include "KRenderingThread.h"
#include "KShaderManager.h"
#include "KMTRender.h"
#include "VImage.h"
#include "KResourceManager.h"

VStackMemoryPool VRenderStackPool(64*1024);

//////////////////////////////////////////////////////////////////////////

#pragma comment(lib, "vRenderD3D9.lib")		// for test 

//////////////////////////////////////////////////////////////////////////
namespace vrc
{

class RC_RenderCommandFence : public VRenderCommand
{
	virtual UINT Execute()
	{
		VInterlockedDecrement((INT*)&m_CommandFence->NumPendingFences);
		return sizeof(RC_RenderCommandFence);
	}
	FRenderCommandFence* m_CommandFence;
public:
	inline RC_RenderCommandFence(FRenderCommandFence* CommandFence) :m_CommandFence(CommandFence)
	{
	}
};
}

void FRenderCommandFence::BeginFence()
{
	VInterlockedIncrement((INT*)&NumPendingFences);
	VPUSH_RENDER_COMMAND(VEnv.Render, vrc::RC_RenderCommandFence, (this));
}

UINT FRenderCommandFence::GetNumPendingFences() const
{
//	CheckRenderingThreadHealth();
	return NumPendingFences;
}

/**
 * Waits for pending fence commands to retire.
 * @param NumFencesLeft	- Maximum number of fence commands to leave in queue
 */
void FRenderCommandFence::Wait( UINT NumFencesLeft/*=0*/ ) const
{
	while(NumPendingFences > (int)NumFencesLeft)
	{
		VSleep(0);
	}
	//check(IsInGameThread());

	//SCOPE_CYCLE_COUNTER(STAT_GameIdleTime);
	//DWORD IdleStart = appCycles();
	//while(NumPendingFences > NumFencesLeft)
	//{
	//	// Check that the rendering thread is still running.
	//	CheckRenderingThreadHealth();

	//	// Yield CPU time while waiting.
	//	appSleep(0);
	//};
	//GGameThreadIdle += appCycles() - IdleStart;
}



VRender::VRender(void):m_SupportInstance(0),m_RI(NULL)
{
}


VRender::~VRender(void)
{
}

BOOL VRender::Init()
{
	// Init Interface
	{
		VASSERT(m_RI == NULL);
		m_RI = VCreateRenderInterface();
	}

	// Register Material Mesh Templates and Shader Fragment class.
	

	StartRenderThread();
	return TRUE;
}

void VRender::Shutdown()
{
	StopRenderThread();

	if (m_RI)
	{
		m_RI->Release();
		m_RI = NULL;
	}
}

BOOL VRender::StartRenderThread()
{
	VASSERT(KRenderThreadInst == NULL);
	KRenderThreadInst = new KRenderingThread;
	if (!KRenderThreadInst->Run())
	{
		VDelete KRenderThreadInst;
		KRenderThreadInst = NULL;
	}
	return TRUE;
}

BOOL VRender::StopRenderThread()
{
	if (KRenderingThread::Instance)
	{
		// wait...

		VDelete KRenderingThread::Instance;
		KRenderingThread::Instance = NULL;
	}
	return TRUE;
}

BOOL VRender::LoadShaderCache()
{
	VASSERT(m_RI);

	return TRUE;
}




VRenderMesh* VRender::RTCreateStaticMesh()
{
	return m_RenderMeshPool->CreateStaticMesh();
}

VTexturePtr VRender::LoadTexture(const char* FileName)
{
	VASSERT(g_ResourceManager);
	return g_ResourceManager->LoadTexture(FileName);
}